package com.lmabbe.gateway.controller;

import com.lmabbe.common.global.constant.RedisKeyConstant;
import com.lmabbe.common.global.context.metadata.client.OauthClient;
import com.lmabbe.common.global.context.metadata.tenant.TenantInfo;
import com.lmabbe.common.global.redis.RedisHelper;
import com.lmabbe.common.global.result.R;
import com.lmabbe.gateway.entity.vo.SystemConfigVO;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author lmabbe
 */
@RestController
@RequestMapping("/system")
@AllArgsConstructor
public class SystemController {

    private final ValueOperations stringOperation;
    private final RedisHelper redisHelper;

    /**
     * 获取系统版本信息
     *
     * @return {@link Mono< R>}
     * @date 2022/1/8 9:56 AM
     * @author liming
     */
    @GetMapping("version")
    public Mono<R> getVersion() {
        return Mono.just(R.success(stringOperation.get(RedisKeyConstant.System.VERSION)));
    }

    /**
     * 获取系统配置
     *
     * @date 2022/1/8 9:57 AM
     * @author liming
     */
    @GetMapping("config")
    public Mono<R<SystemConfigVO>> getConfig() {
        Set<String> scan = redisHelper.scan(RedisKeyConstant.System.BASE + RedisKeyConstant.System.Tenant.BASE);

        Set<Long> tenantList = scan.stream().map(s -> Long.parseLong(s.split(":")[2])).collect(Collectors.toSet());

        List<SystemConfigVO.TenantsVO> tenantsVOS = new ArrayList<>();
        for (Long s : tenantList) {
            tenantsVOS.add(buildConfigTenantInfo(s));
        }

        return Mono.just(R.success(new SystemConfigVO().setTenants(tenantsVOS)));
    }

    /**
     * 组装租户信息
     *
     * @param tenantId 租户ID
     * @return {@link SystemConfigVO}
     * @date 2022/1/8 11:08 AM
     * @author liming
     */
    private SystemConfigVO.TenantsVO buildConfigTenantInfo(Long tenantId) {

        List<OauthClient> oauthClients = (List<OauthClient>) stringOperation.
                get(String.format(RedisKeyConstant.System.Tenant.TENANT_CLIENT, tenantId));

        return new SystemConfigVO.TenantsVO()
                .setTenantId(tenantId)
                .setTenantInfo((TenantInfo) stringOperation.get(String.format(RedisKeyConstant.System.Tenant.TENANT_INFO, tenantId)))
                .setClients(
                        oauthClients.stream()
                                .map(s -> new SystemConfigVO.TenantsVO.OauthClientVO(s.getClientKey(), s.getClientSecret()))
                                .collect(Collectors.toList())
                );
    }
}
